home *** CD-ROM | disk | FTP | other *** search
- #include <fcntl.h>
- #include <unistd.h>
- #include <limits.h>
- #include <signal.h>
- #include "netconf.h"
- #include "internal.h"
- #include "../paths.h"
- #include "../xconf/xconf.h"
- #include "netconf.m"
-
- static NETCONF_HELP_FILE help_inetd("inetd");
- static CONFIG_FILE f_inetd (ETC_INETD_CONF,help_inetd,CONFIGF_PROBED);
- static NETCONF_HELP_FILE help_amd("amd");
- static CONFIG_FILE f_conf_amd (ETC_CONF_AMD_MAP,help_amd,CONFIGF_PROBED);
- static NETCONF_HELP_FILE help_gated("gated");
- static CONFIG_FILE f_gated (ETC_GATED_CONF,help_gated,CONFIGF_PROBED);
- static NETCONF_HELP_FILE help_ssh ("ssh");
- static CONFIG_FILE f_ssh_host_key (ETC_SSH_HOST_KEY,help_ssh,CONFIGF_PROBED);
-
-
- extern CONFIG_FILE f_exports;
-
-
- /* #Specification: daemon / classes
- The class DAEMON is the base class. Each daemon (portmap, inetd, ...)
- may have its own class where it generally overide the method
- startif and stop.
- */
- #
- class DAEMON_INETD: public DAEMON{
- /*~PROTOBEG~ DAEMON_INETD */
- public:
- int restart (void);
- int startif (void);
- /*~PROTOEND~ DAEMON_INETD */
- };
- /*
- Tell inetd to reread its configuration file
- */
- PUBLIC int DAEMON_INETD::restart()
- {
- int ret = -1;
- PROC *prc = process_find(path);
- if (prc != NULL){
- if (file_date (VAR_RUN_INETD_SIGHUP) < f_inetd.getdate()){
- ret = signal (SIGHUP,"Signaling",VAR_RUN_INETD_SIGHUP);
- }
- }
- return ret;
- }
- PUBLIC int DAEMON_INETD::startif()
- {
- /* #Specification: inetd / strategy
- inetd depend on /etc/inetd.conf. If the file is empty
- or do not exist, then inetd is not need. It will be
- killed, or not started.
-
- If inetd.conf is not empty, it will be started. If it is
- already running and exports is younger than the process,
- the signal SIGHUP is sent so inetd will reread inetd.conf.
- */
- return startif_file(ETC_INETD_CONF);
- }
- class DAEMON_PORTMAP: public DAEMON{
- /*~PROTOBEG~ DAEMON_PORTMAP */
- /*~PROTOEND~ DAEMON_PORTMAP */
- };
-
- class DAEMON_AMD: public DAEMON{
- /*~PROTOBEG~ DAEMON_AMD */
- public:
- int restart (void);
- int startif (void);
- int stop (void);
- /*~PROTOEND~ DAEMON_AMD */
- };
- /*
- Stop the automounter
- */
- PUBLIC int DAEMON_AMD::stop ()
- {
- return kill(SIGINT);
- }
- /*
- Tell the automounter to reread its configuration file.
- */
- PUBLIC int DAEMON_AMD::restart ()
- {
- /* #Specification: amd / restarting
- When the map (/etc/conf.amd.map) is changed, amd is simply
- restarted. It is killed with SIGINT and restarted. This is
- weak as it is unmounting everything. On the other hand
- I suspect that amd will be managed only in single user
- mode so it does not matter. Some amd guru want to comment.
- */
- int ret = stop();
- if (ret != -1) ret = start();
- return ret;
- }
- /*
- Restart amd if ETC_CONF_AMD_MAP is newer than the process
- */
- PUBLIC int DAEMON_AMD::startif ()
- {
- /* #Specification: amd automounter / strategy
- amd depends on /etc/conf.amd.map. If the file is empty
- or do not exist, then amd is not need. It will be
- killed, or not started.
-
- If /etc/conf.amd.map is not empty, it will be started. If it is
- already running and exports is younger than the process,
- it will be kill and restart
- */
- return startif_file (f_conf_amd);
- }
- class DAEMON_LPD: public DAEMON{
- /*~PROTOBEG~ DAEMON_LPD */
- /*~PROTOEND~ DAEMON_LPD */
- };
- class DAEMON_NFSD: public DAEMON{
- /*~PROTOBEG~ DAEMON_NFSD */
- public:
- int startif (void);
- /*~PROTOEND~ DAEMON_NFSD */
- };
- /*
- Restart nfsd if ETC_EXPORTS is newer than the process
- */
- PUBLIC int DAEMON_NFSD::startif ()
- {
- /* #Specification: rpc.nfsd / strategy
- rpc.nfsd depends on /etc/exports. If the file is empty
- or do not exist, then rpc.nfsd is not need. It will be
- killed, or not started.
-
- If exports is not empty, it will be started. If it is
- already running and exports is younger than the process,
- it will be kill and restart.
-
- I suspect there is a way to update nfsd without killing it.
- Someone is aware of this ?
- */
- return startif_file(f_exports);
- }
- class DAEMON_MOUNTD: public DAEMON{
- /*~PROTOBEG~ DAEMON_MOUNTD */
- public:
- int startif (void);
- /*~PROTOEND~ DAEMON_MOUNTD */
- };
-
- /*
- Restart mountd if ETC_EXPORTS is newer than the process
- */
- PUBLIC int DAEMON_MOUNTD::startif ()
- {
- /* #Specification: rpc.mountd / strategy
- rpc.mountd depends on /etc/exports. If the file is empty
- or do not exist, then rpc.mountd is not need. It will be
- killed, or not started.
-
- If exports is not empty, it will be started. If it is
- already running and exports is younger than the process,
- it will be kill and restart
- */
- return startif_file(f_exports);
- }
- class DAEMON_NAMED: public DAEMON{
- /*~PROTOBEG~ DAEMON_NAMED */
- public:
- int startif (void);
- /*~PROTOEND~ DAEMON_NAMED */
- };
- /*
- Restart named if ETC_NAMED_BOOT is newer than the process
- */
- PUBLIC int DAEMON_NAMED::startif ()
- {
- /* #Specification: named / strategy
- named depends on /etc/named.boot and many others configuration
- files. If the file is empty or do not exist, then named
- is not need. It will be killed, or not started.
-
- If named.boot is not empty, it will be started. If it is
- already running and named.boot is younger than the process,
- it will be killed and restarted.
-
- This is not completed yet. Normally, we should check for all
- file processed by named to check if any one is younger. This
- is not done now, as another project (the named editor) will
- take care of named.
- */
- extern CONFIG_FILE f_boot;
- return startif_file(f_boot);
- }
-
- class DAEMON_GATED: public DAEMON{
- /*~PROTOBEG~ DAEMON_GATED */
- public:
- int restart (void);
- int start (void);
- int startif (void);
- int stop (void);
- /*~PROTOEND~ DAEMON_GATED */
- };
- /*
- Restart gated if ETC_GATED_CONF is newer than the process
- */
- PUBLIC int DAEMON_GATED::startif ()
- {
- /* #Specification: gated / strategy
- gated depends on /etc/gated.conf.
- If the file is empty or do not exist, then gated
- is not need. It will be killed, or not started.
-
- If gated.conf is not empty, it will be started. If it is
- already running and gated.conf is younger than the process,
- it will be kill and restart.
-
- */
- return startif_file(f_gated);
- }
-
- /*
- Tell gated to reread its configuration file
- */
- PUBLIC int DAEMON_GATED::restart()
- {
- char buf[2000];
- sprintf (buf,"%s restart",path);
- return system (buf);
- }
- /*
- Tell gated to stop
- */
- PUBLIC int DAEMON_GATED::stop()
- {
- int ret = 0;
- if (process_find(path)!=NULL){
- char buf[2000];
- sprintf (buf,"%s stop",path);
- ret = system (buf);
- }
- return ret;
- }
- /*
- Tell gated to start
- */
- PUBLIC int DAEMON_GATED::start()
- {
- char buf[2000];
- sprintf (buf,"%s start",path);
- return system (buf);
- }
- class DAEMON_SENDMAIL: public DAEMON{
- /*~PROTOBEG~ DAEMON_SENDMAIL */
- public:
- int startif (void);
- /*~PROTOEND~ DAEMON_SENDMAIL */
- };
- /*
- Restart sendmail if ETC_SENDMAIL_CF is newer than the process
- */
- PUBLIC int DAEMON_SENDMAIL::startif ()
- {
- /* #Specification: sendmail / strategy
- sendmail depends on /etc/sendmail.cf.
- If the file is empty or do not exist, then sendmail
- is not need. It will be killed, or not started.
-
- If sendmail.cf is not empty, it will be started. If it is
- already running and sendmail.cf is younger than the process,
- it will be kill and restart.
-
- */
- extern CONFIG_FILE f_sendmail;
- return startif_file(f_sendmail);
- }
- class DAEMON_ROUTED: public DAEMON{
- /*~PROTOBEG~ DAEMON_ROUTED */
- private:
- void setcmdline (ROUTED&rt, char *cmdline);
- public:
- int start (void);
- int startif (void);
- /*~PROTOEND~ DAEMON_ROUTED */
- };
-
- PRIVATE void DAEMON_ROUTED::setcmdline(ROUTED &rt, char *cmdline)
- {
- char buf[20];
- rt.setoptions (buf);
- sprintf (cmdline,"%s %s %s",path,args,buf);
- }
- extern NETCONF_HELP_FILE help_routed;
- static CONFIG_FILE f_run_routed (VAR_RUN_ROUTED_OPTIONS
- ,help_routed,CONFIGF_MANAGED|CONFIGF_OPTIONNAL);
-
- PUBLIC int DAEMON_ROUTED::start()
- {
- ROUTED rt;
- char cmdline[PATH_MAX];
- setcmdline (rt,cmdline);
- if (!simul_ison()){
- FILE *fout = f_run_routed.fopen ("w");
- if (fout != NULL){
- fputs (cmdline,fout);
- fclose (fout);
- }
- }
- return system (cmdline);
- }
- PUBLIC int DAEMON_ROUTED::startif()
- {
- int ret = 0;
- ROUTED rt;
- if (!rt.is_required()){
- ret = stop();
- if (!simul_ison()) unlink (f_run_routed.getpath());
- }else{
- PROC *prc = process_find(path);
- if (prc == NULL){
- ret = start();
- }else{
- /* #Specification: netconf / routed / /var/run/routed.options
- netconf save the command line option of routed in
- the file /var/run/routed.options each time it is
- started.
-
- When checking the configuration, netconf read back
- the command line and compare with the configured
- one. If there is any difference, routed will
- be restarted.
-
- I am not sure how appropriate it is to
- restarted. Maybe there is a clean way to kill routed
- so it will remove all routes and put it back when
- restart. Not sure here...
- */
- char old_cmdline[PATH_MAX];
- old_cmdline[0] = '\0';
- FILE *fin = f_run_routed.fopen ("r");
- if (fin != NULL){
- fgets (old_cmdline,sizeof(old_cmdline)-1,fin);
- fclose (fin);
- }
- char cmdline[PATH_MAX];
- setcmdline (rt,cmdline);
- if (strcmp(cmdline,old_cmdline)!=0) ret = restart();
- }
- }
- return ret;
- }
-
-
-
- class DAEMON_YPBIND: public DAEMON{
- /*~PROTOBEG~ DAEMON_YPBIND */
- private:
- int set_domain (NIS_CONF&nis);
- public:
- int start (void);
- int startif (void);
- /*~PROTOEND~ DAEMON_YPBIND */
- };
-
- /*
- Set the NIS domain name.
- Return -1 if not defined, 0 if left unchanged or 1 if changed
- */
- PRIVATE int DAEMON_YPBIND::set_domain(NIS_CONF &nis)
- {
- int ret = -1;
- if (nis.configok()){
- ret = 0;
- const char *domain = nis.getdomain();
- char buf[100];
- if (getdomainname(buf,sizeof(buf)-1)==-1
- || strcmp(buf,domain)!=0){
- if (!simul_ison()){
- setdomainname(domain,strlen(domain)+1);
- }
- ret = 1;
- net_prtlog (MSG_U(X_SETNISDOM,"Set NIS domain to %s\n"),domain);
- }
- }
- return ret;
- }
- /*
- Start ypbind.
- */
- PUBLIC int DAEMON_YPBIND::start ()
- {
- int ret = 0;
- NIS_CONF nis;
- if (set_domain(nis) != -1){
- const char *nisserver = nis.getserver();
- if (nisserver != NULL){
- char buf[2000];
- sprintf (buf,"%s -ypset %s",path,args);
- ret = -1;
- if (system (buf) == 0){
- char ypset_path[PATH_MAX];
- strcpy (ypset_path,path);
- char *pt = ypset_path + strlen(ypset_path) -1;
- while (pt >= ypset_path && *pt != '/') pt--;
- if (pt >= ypset_path && *pt == '/'){
- *pt = '\0';
- sprintf(buf,"%s/ypset %s",ypset_path,nisserver);
- }else{
- sprintf(buf,"ypset %s",nisserver);
- }
- ret = system (buf);
- }
- }else{
- ret = DAEMON::start();
- }
- }
- return ret;
- }
- /*
- Restart ypbind if ETC_DEFAULTDOMAIN is newer than the process
- */
- PUBLIC int DAEMON_YPBIND::startif ()
- {
- /* #Specification: ypbind / strategy
- ypbind is configured in the file /etc/conf.linuxconf
- It provides the nis domain and optionnally the nis server
- (If it can't be located by a broadcast).
-
- If the nis domain is defined, then ypbind is started.
- Depending if a server is specified or not,
- ypbind is started this way:
-
- #
- No specified NIS server
-
- ypbind
-
- With a specified NIS server
-
- ypbind -ypset
- ypset -h nisserver
- #
-
- If the configuration file is newer than the current process,
- it is killed and restarted.
- */
- int ret = 0;
- NIS_CONF nis;
- int status = set_domain(nis);
- if (status == -1){
- ret = stop();
- }else if (status == 0){
- if (process_find(path)==NULL) ret = start();
- }else{
- ret = restart();
- }
- return ret;
- }
- class DAEMON_KLOGD: public DAEMON{
- /*~PROTOBEG~ DAEMON_KLOGD */
- /*~PROTOEND~ DAEMON_KLOGD */
- };
- class DAEMON_SYSLOGD: public DAEMON{
- /*~PROTOBEG~ DAEMON_SYSLOGD */
- /*~PROTOEND~ DAEMON_SYSLOGD */
- };
- // Not really a daemon, but a system command
- class DAEMON_COMMAND: public DAEMON{
- /*~PROTOBEG~ DAEMON_COMMAND */
- /*~PROTOEND~ DAEMON_COMMAND */
- };
- class DAEMON_CROND: public DAEMON{
- /*~PROTOBEG~ DAEMON_CROND */
- /*~PROTOEND~ DAEMON_CROND */
- };
- class DAEMON_KERNELD: public DAEMON{
- /*~PROTOBEG~ DAEMON_KERNELD */
- /*~PROTOEND~ DAEMON_KERNELD */
- };
- class DAEMON_SSHD: public DAEMON{
- /*~PROTOBEG~ DAEMON_SSHD */
- public:
- int startif (void);
- /*~PROTOEND~ DAEMON_SSHD */
- };
-
- /*
- Restart sshd if ETC_SSH_HOST_KEY is newer than the process
- */
- PUBLIC int DAEMON_SSHD::startif ()
- {
- /* #Specification: sshd / strategy
- sshd depends on /etc/ssh_host_key at least.
- If the file is empty or do not exist, then sshd
- is not need. It will be killed, or not started.
-
- If ssh_host_key is not empty, it will be started. If it is
- already running and the file is younger than the process,
- it will be kill and restart.
-
- */
- return startif_file(f_ssh_host_key);
- }
-
- /*
- Create an instance of a sub-class of DAEMON based on its name.
- */
- DAEMON *daemon_new (
- int managed,
- const char *name,
- const char *buf,
- DAEMON *next)
- {
- DAEMON *ret = NULL;
- #define NEWD(n,c) if(strcmp(name,n)==0){ \
- ret = new DAEMON_##c; \
- }
- NEWD("inetd",INETD)
- else NEWD ("chat",COMMAND)
- else NEWD ("crond",CROND)
- else NEWD ("rpc.portmap",PORTMAP)
- else NEWD ("named",NAMED)
- else NEWD ("routed",ROUTED)
- else NEWD ("ypbind",YPBIND)
- else NEWD ("amd",AMD)
- else NEWD ("klogd",KLOGD)
- else NEWD ("syslogd",SYSLOGD)
- else NEWD ("rpc.nfsd",NFSD)
- else NEWD ("rpc.mountd",MOUNTD)
- else NEWD ("lpd",LPD)
- else NEWD ("ifconfig",COMMAND)
- else NEWD ("ipx_configure",COMMAND)
- else NEWD ("ipx_interface",COMMAND)
- else NEWD ("kerneld",KERNELD)
- else NEWD ("route",COMMAND)
- else NEWD ("clock",COMMAND)
- else NEWD ("rarp",COMMAND)
- else NEWD ("lilo",COMMAND)
- else NEWD ("netdate",COMMAND)
- else NEWD ("makemap",COMMAND)
- else NEWD ("modprobe",COMMAND)
- else NEWD ("depmod",COMMAND)
- else NEWD ("pppd",COMMAND)
- else NEWD ("fdisk",COMMAND)
- else NEWD ("telinit",COMMAND)
- else NEWD ("mount",COMMAND)
- else NEWD ("nslookup",COMMAND)
- else NEWD ("umount",COMMAND)
- else NEWD ("gated",GATED)
- else NEWD ("sendmail",SENDMAIL)
- else NEWD ("sshd",SSHD)
- else{
- xconf_error (MSG_U(E_UNKNOWNDAEMON
- ,"Unknown daemon :%s:....\ndon't know how to support it\n")
- ,name);
- }
- if (ret != NULL){
- ret->init(managed,name,buf,next);
- }
- return ret;
- }
-
-